package com.superzlc.vjoy;

import java.util.Scanner;

import com.superzlc.vjoy.socket.BroadcastServer;
import com.superzlc.vjoy.socket.MessageOp.VJoyPackage;
import com.superzlc.vjoy.socket.MessageServer;

public class VJoyServer {

	public static void main(String[] args) {
		VJoyServer s = new VJoyServer();
		s.start();
		System.out.println("输入exit以结束：");
		Scanner sc = new Scanner(System.in);
		while(true) {
			String line = sc.nextLine();
			if ("exit".equals(line)) {
				s.shutdown();
				break;
			}
		}
		sc.close();
	}

	BroadcastServer broadcastServer;
	MessageServer messageServer;

	public void start() {
		broadcastServer = new BroadcastServer();
		messageServer = new MessageServer();
		messageServer.setVjoyServer(this);
		if (AcquireVJD() == 0) {
			broadcastServer.startup();
			messageServer.startup();
		}
	}

	public void finalize() {
		this.shutdown();
	}

	public void shutdown() {
		broadcastServer.shutdown();
		messageServer.shutdown();
		this.relinquishVJD();
	}

	int devId = 1;
	VJoy vjoy = VJoy.getInstance();

	private int AcquireVJD() {

		// 获取设备属性 (Vendor ID, Product ID, Version Number)
		if (!vjoy.vJoyEnabled()) {
			print("vJoy不可用，请确保安装了vJoy并且没有禁用");
			vjoy.RelinquishVJD(devId);
			return -2;
		}

		print("制造商(vJoyManufacturer): %s", vjoy.GetvJoyManufacturerString());
		print("产品(vJoyProduct): %s", vjoy.GetvJoyProductString());
		print("版本(vJoyVersion): %d", vjoy.GetvJoyVersion());
		print("序列号(vJoySerialNumber): %s", vjoy.GetvJoySerialNumberString());
		print("是否支持力反馈(JoyFfbCap): %s", vjoy.vJoyFfbCap() ? "true" : "false");
		print("最大虚拟设备个数(vJoyMaxDevices): %s", vjoy.GetvJoyMaxDevices());
		print("存在虚拟设备个数(NumberExistingVJD): %s", vjoy.GetNumberExistingVJD());

		// 设备状态属性
		if (!vjoy.isVJDExists(devId)) {
			print("虚拟设备#%d不存在\n", devId);
			return -1;
		}
		int pid = vjoy.GetOwnerPid(devId);
		print("虚拟设备#%d的 OwnerPid: %d", devId, pid);

		int status = vjoy.GetVJDStatus(devId);
		switch (status) {
		case VJoy.VJD_STAT_OWN:
			print("虚拟设备#%d已经被占用", devId);
			break;
		case VJoy.VJD_STAT_FREE:
			print("虚拟设备#%d空闲，可以接收占用", devId);
			break;
		case VJoy.VJD_STAT_BUSY:
			print("虚拟设备#%d忙碌，已经被另一个终端占用", devId);
			return -3;
		case VJoy.VJD_STAT_MISS:
			print("虚拟设备#%d丢失，没有安装或已经被禁用", devId);
			return -4;
		default:
			print("虚拟设备#%d发生了错误", devId);
			return -1;
		};

		print("虚拟设备#%d按钮数(VJDButtonNumber): %d", devId, vjoy.GetVJDButtonNumber(devId));
		print("虚拟设备#%d离散苦力帽Number(VJDDiscPovNumber): %d", devId, vjoy.GetVJDDiscPovNumber(devId));
		print("虚拟设备#%d连续苦力帽Number(VJDContPovNumber): %d", devId, vjoy.GetVJDContPovNumber(devId));

		for (int axis : new int[]{
				VJoy.HID_USAGE_X,
				VJoy.HID_USAGE_Y,
				VJoy.HID_USAGE_Z,
				VJoy.HID_USAGE_RX,
				VJoy.HID_USAGE_RY,
				VJoy.HID_USAGE_RZ,
				VJoy.HID_USAGE_SL0,
				VJoy.HID_USAGE_SL1,
				VJoy.HID_USAGE_WHL,
				VJoy.HID_USAGE_POV,
				}) {
			boolean b = vjoy.GetVJDAxisExist(devId, axis);
			if (!b) {
				print("虚拟设备#%d不存在轴 %d", devId, axis);
				continue;
			}
			long max = vjoy.GetVJDAxisMax(devId, axis);
			long min = vjoy.GetVJDAxisMin(devId, axis);
			print("虚拟设备#%d轴%d值范围： %d : %d", devId, axis, min, max);
		}

		// 获取设备
		if (!vjoy.AcquireVJD(devId)) {
			print("获取虚拟设备#%d失败", devId);
			vjoy.RelinquishVJD(devId);
			return -1;
		} else {
			print("获取虚拟设备#%d成功", devId);
		}

		return 0;
	}

	private void relinquishVJD() {
		// 释放
		print("释放虚拟设备#%d", devId);
		vjoy.RelinquishVJD(devId);
	}

	VJoy.JoyStickPosition data;
	public void ctrl(VJoyPackage pkg) {
		if (data == null) {
			data = new VJoy.JoyStickPosition();
			data.bDevice = (byte)devId;
			vjoy.ResetAll();
		}
		data.setX(pkg.getAsix(0));
		data.setY(pkg.getAsix(1));
		data.setZ(pkg.getAsix(2));
		data.setRX(pkg.getAsix(3));
		data.setRY(pkg.getAsix(4));
		data.setRZ(pkg.getAsix(5));
		data.setSL0_wSlider(pkg.getAsix(6));
		data.setSL1_wDial(pkg.getAsix(7));
		for (int i = 0; i < 32; i++) {
			data.setButton(i, pkg.getBtnPressed(i));
		}
		if (!vjoy.UpdateVJD(devId, data)) {
			vjoy.AcquireVJD(devId);
		}
	}

	static void print(String format, Object ... args) {
		if (args.length == 0)
			System.out.println(format);
		else
			System.out.println(String.format(format, args));
	}
}
